package com.UnionPayCenter.controller;

import com.UnionPayCenter.account.enums.PayStatusEnum;
import com.UnionPayCenter.constant.ComponentConstants;
import com.UnionPayCenter.constant.ConstantInterface;
import com.UnionPayCenter.entity.ConfEntity;
import com.UnionPayCenter.entity.ResponseWrapper;
import com.UnionPayCenter.entity.vo.MpQrCodeVO;
import com.UnionPayCenter.enums.ErrorCodeEnum;
import com.UnionPayCenter.exception.ApiException;
import com.UnionPayCenter.mapper.ConfMapper;
import com.UnionPayCenter.service.FundsAccountService;
import com.UnionPayCenter.service.IComponentService;
import com.UnionPayCenter.service.IUserService;
import com.UnionPayCenter.service.IWechatService;
import com.UnionPayCenter.swagger.ApiJsonObject;
import com.UnionPayCenter.swagger.ApiJsonProperty;
import com.UnionPayCenter.util.Asserts;
import com.UnionPayCenter.util.StringUtils;
import com.UnionPayCenter.wechat.WeixinUtil;
import com.alibaba.fastjson.JSONObject;
import com.google.common.collect.Lists;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.List;

/**
 * @program: UnionPayCenter
 * @description: 微信回调
 * @author: bite
 * @create:
 **/
@Slf4j
@RestController
@Api(value = "wechatBack", tags = "微信回调")
public class WechatController {
    @Autowired
    private FundsAccountService fundsAccountService;

    @Autowired
    private IUserService userService;

    @Autowired
    private IWechatService wechatService;

    @Autowired
    private IComponentService componentService;

    @Autowired
    private ConfMapper confMapper;

//    @RequestMapping(value = "/wechatPayBack")
//    public void wechatPayBack(HttpServletRequest request, HttpServletResponse response){
//        try {
//            InputStream inStream = request.getInputStream();
//            ByteArrayOutputStream outSteam = new ByteArrayOutputStream();
//            byte[] buffer = new byte[1024];
//            int len = 0;
//            while ((len = inStream.read(buffer)) != -1) {
//                outSteam.write(buffer, 0, len);
//            }
//            String resultStr  = new String(outSteam.toByteArray(),"utf-8");
//            outSteam.close();
//            inStream.close();
//            Map<String, Object> resultMap = WechatPayUtil.xmltoMap(resultStr);
////			String result_code = (String) resultMap.get("result_code");
////			String is_subscribe = (String) resultMap.get("is_subscribe");
////			String transaction_id = (String) resultMap.get("transaction_id");
////			String sign = (String) resultMap.get("sign");
////			String time_end = (String) resultMap.get("time_end");
////			String bank_type = (String) resultMap.get("bank_type");
//
//            String out_trade_no = (String) resultMap.get("out_trade_no");
//            String return_code = (String) resultMap.get("return_code");
//
//            if(return_code.equals("SUCCESS")){
//                fundsAccountService.wechatPayBack(out_trade_no, PayStatusEnum.SUCCESS);
//            }else{
//                fundsAccountService.wechatPayBack(out_trade_no, PayStatusEnum.FAIL);
//            }
//
//            //通知微信.异步确认成功.必写.不然微信会一直通知后台.八次之后就认为交易失败了.
//            response.getWriter().write(WechatPayUtil.setXML("SUCCESS", ""));
//        }  catch (Exception e) {
//            e.printStackTrace();
//            try {
//                response.getWriter().write(WechatPayUtil.setXML("FAIL", "error"));
//            } catch (IOException e1) {
//				e1.printStackTrace();
//            }
//        }
//
//    }

    @RequestMapping(value = "/vastchain/wechatPayBack", method = RequestMethod.POST)
    @ApiOperation(tags = "微信回调", httpMethod = "POST", value = "[vastchain]微信支付回调", response = String.class)
    public String vastchainWechatPayBack(@RequestBody JSONObject json) {
        try {
            //TODO
//            请务必按照要求返回 OK，否则系统会认为回调异常并继续重复调用该回调。
//            系统可能会多次调用回调，所以请务必做好重复判断，要能正确处理回调多次被调用的情况。
//            为了防止假冒的回调，请务必验证宇链云发给你的请求中的签名（也就是调用回调时地址中附带的查询字段 _s 字段）是否正确。同时必须验证 notifyTime 不能和当前时间差距太大（推荐 3 分钟内作为合法）。具体请参考签名说明。
//            如果回调不成功会自动重试至少 12 次以上，每次时间间隔逐步增加，以尽量确保回调成功。
            log.info(String.format("微信支付回调，参数：%s", json.toJSONString()));
            String prepayId = json.getString("prepayId");//相关的预支付单号
            String status = json.getString("status");//可能为 finish（代表支付完成）或者 refunded（代表退款完成）
            String subMerchantId = json.getString("subMerchantId");//对应的子商户号
            String merchantId = json.getString("merchantId");//对应的父商户号
            String notifyTime = json.getString("notifyTime");//回调时间
            JSONObject paymentExtra = json.getJSONObject("paymentExtra");//里面有两个成员：paymentMethod 和  paymentProviderTrxId
            String paymentProviderTrxId = paymentExtra.getString("paymentProviderTrxId");
            String paymentMethod = paymentExtra.getString("paymentMethod");//银联支付：WechatUnionPayBizSmall 微信支付：WechatNative
            if (status.equals("finish")) {
                Integer userId = fundsAccountService.wechatPayBack(prepayId, PayStatusEnum.SUCCESS);
                if (userId != null && !StringUtils.isNullStr(paymentProviderTrxId)) {
                    userService.getPaidUnionId(userId, paymentProviderTrxId);
                }
            } else {
                fundsAccountService.wechatPayBack(prepayId, PayStatusEnum.FAIL);
            }
            return "OK";
        } catch (Exception e) {
            log.error(String.format("[vastchain]微信支付回调失败"), e);
            return "FAIL";
        }

    }

    @RequestMapping(value = "/wechat/mpback", method = RequestMethod.GET)
    @ApiOperation(tags = "微信回调", httpMethod = "GET", value = "[微信]微信回调", response = String.class)
    public void wechatMpBackGet(HttpServletRequest request, HttpServletResponse response) {
        String signature = request.getParameter("signature");
        String timestamp = request.getParameter("timestamp");
        String nonce = request.getParameter("nonce");
        String echostr = request.getParameter("echostr");
        PrintWriter out = null;
        try {
            out = response.getWriter();
            if (WeixinUtil.checkSignature(ConstantInterface.WX_TOKEN_KEY, signature, timestamp, nonce)) {
                out.write(echostr);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            out.close();
        }
    }

    @RequestMapping(value = "/wechat/mpback", method = RequestMethod.POST)
    @ApiOperation(tags = "微信回调", httpMethod = "POST", value = "[微信]微信回调", response = String.class)
    public void wechatMpBackPost(HttpServletRequest request, HttpServletResponse response) throws Exception {
        // 将请求、响应的编码均设置为UTF-8（防止中文乱码）
        request.setCharacterEncoding("UTF-8");
        response.setCharacterEncoding("UTF-8");

        // 微信加密签名
        String signature = request.getParameter("signature");
        // 时间戳
        String timestamp = request.getParameter("timestamp");
        // 随机数
        String nonce = request.getParameter("nonce");

        PrintWriter out = response.getWriter();
        // 通过检验signature对请求进行校验，若校验成功r，表示接入成功，否则接入失败
        if (WeixinUtil.checkSignature(ConstantInterface.WX_TOKEN_KEY, signature, timestamp, nonce)) {
            // 调用核心业务类接收消息、处理消息
            String respMessage = wechatService.mpBack(request, response);
            // 响应消息
            out.print(respMessage);
            out.close();
        }
    }

    /**
     * @Description: 授权事件接受url 每隔10分钟 获取微信服务器推送ticket 接收后需要解密 接收到后 必须返回字符串success
     * @Param:
     * @return:
     * @Author: bite
     * @Date: 2019/7/21
     */
    @RequestMapping(value = "/wechat/openback", method = RequestMethod.POST)
    @ApiOperation(tags = "微信回调", httpMethod = "POST", value = "[微信]授权事件接收", response = String.class)
    public void wechatOpenBackPost(HttpServletRequest request, HttpServletResponse response) throws Exception {
        // 将请求、响应的编码均设置为UTF-8（防止中文乱码）
        request.setCharacterEncoding("UTF-8");
        response.setCharacterEncoding("UTF-8");

        // 微信加密签名
        String signature = request.getParameter("signature");
        // 时间戳
        String timestamp = request.getParameter("timestamp");
        // 随机数
        String nonce = request.getParameter("nonce");

        PrintWriter out = response.getWriter();
        // 通过检验signature对请求进行校验，若校验成功r，表示接入成功，否则接入失败
        if (WeixinUtil.checkSignature(ComponentConstants.COMPONENT_TOKEN, signature, timestamp, nonce)) {
            String respMessage = componentService.openBack(request, response);
            // 响应消息1
            out.print(respMessage);
            out.close();
        }
    }


    @RequestMapping(value = "/wechat/{appid}/mpback", method = RequestMethod.GET)
    @ApiOperation(tags = "微信回调", httpMethod = "GET", value = "[微信]微信回调", response = String.class)
    public void wechatAppidMpBackGet(@PathVariable String appid, HttpServletRequest request, HttpServletResponse response) {
        String signature = request.getParameter("signature");
        String timestamp = request.getParameter("timestamp");
        String nonce = request.getParameter("nonce");
        String echostr = request.getParameter("echostr");
        PrintWriter out = null;
        try {
            out = response.getWriter();
            if (WeixinUtil.checkSignature(ComponentConstants.COMPONENT_TOKEN, signature, timestamp, nonce)) {
                out.write(echostr);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            out.close();
        }
    }

    @RequestMapping(value = "/wechat/{appid}/mpback", method = RequestMethod.POST)
    @ApiOperation(tags = "微信回调", httpMethod = "POST", value = "[微信]微信回调", response = String.class)
    public void wechatAppidMpBackPost(@PathVariable String appid, HttpServletRequest request, HttpServletResponse response) throws Exception {
        // 将请求、响应的编码均设置为UTF-8（防止中文乱码）
        request.setCharacterEncoding("UTF-8");
        response.setCharacterEncoding("UTF-8");

        // 微信加密签名
        String signature = request.getParameter("signature");
        // 时间戳
        String timestamp = request.getParameter("timestamp");
        // 随机数
        String nonce = request.getParameter("nonce");

        PrintWriter out = response.getWriter();
        // 通过检验signature对请求进行校验，若校验成功r，表示接入成功，否则接入失败
        if (WeixinUtil.checkSignature(ComponentConstants.COMPONENT_TOKEN, signature, timestamp, nonce)) {
            // 调用核心业务类接收消息、处理消息
            String respMessage = componentService.mpBack(appid, request, response);
            // 响应消息
            out.print(respMessage);
            out.close();
        }
    }

    @RequestMapping(value = "/wechat/mp/qrcode", method = RequestMethod.POST)
    @ApiOperation(tags = "微信回调", httpMethod = "POST", value = "[后台]小程序码", response = String.class)
    public ResponseWrapper mpQrCode(
            @ApiJsonObject(name = "qrCodeParams", value = {
                    @ApiJsonProperty(key = "token", value = "token值"),
                    @ApiJsonProperty(key = "shopId", value = "商铺id", type = "int")
            }) @RequestBody JSONObject jsonParam) {
        Integer shopId = jsonParam.getInteger("shopId");
        Asserts.notNull(shopId, "店铺Id");
        String basePath = "/usr/local/images/unlimited-" + shopId;
        String userCenterPath = basePath + "user-center.jpg";
        String payPath = basePath + "pay.jpg";
        String chargePath = basePath + "distribution.jpg";
        boolean success = wechatService.getUnlimited(shopId, shopId, userCenterPath, "pages/user/index");
        if (success) {
            success = wechatService.getUnlimited(shopId, shopId, payPath, "pages/pay/index");
        }
        if (success) {
            success = wechatService.getUnlimited(shopId, shopId, chargePath, "pages/distribution/index");
        }
        if (success) {
            ConfEntity confEntity = confMapper.selectByKey(ConstantInterface.LEGAL_URL);
            String host = confEntity.getConfValue();
            List<MpQrCodeVO> mpQrCodeVOList = Lists.newArrayList();
            MpQrCodeVO userCenterMpQrCodeVO = new MpQrCodeVO();
            userCenterMpQrCodeVO.setName("userCenter");
            userCenterMpQrCodeVO.setUrl(host + "/images/unlimited-" + shopId + "user-center.jpg");
            mpQrCodeVOList.add(userCenterMpQrCodeVO);

            MpQrCodeVO payMpQrCodeVO = new MpQrCodeVO();
            payMpQrCodeVO.setName("pay");
            payMpQrCodeVO.setUrl(host + "/images/unlimited-" + shopId + "pay.jpg");
            mpQrCodeVOList.add(payMpQrCodeVO);

            //MpQrCodeVO chargeMpQrCodeVO = new MpQrCodeVO();
            //chargeMpQrCodeVO.setName("distribution");
            //chargeMpQrCodeVO.setUrl(host + "/images/unlimited-" + shopId + "distribution.jpg");
            //mpQrCodeVOList.add(chargeMpQrCodeVO);

            return ResponseWrapper.succeed(mpQrCodeVOList);
        }
        throw new ApiException(ErrorCodeEnum.WD11001);
    }
}
